home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / bbs / termv4.6 / extras / source / term-source.lha / Hotkeys.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-18  |  7.3 KB  |  431 lines

  1. /*
  2. **    Hotkeys.c
  3. **
  4. **    Hotkey support routines.
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #ifndef _GLOBAL_H
  11. #include "Global.h"
  12. #endif
  13.  
  14. enum    {    CX_TERMSCREENTOFRONT,CX_BUFFERSCREENTOFRONT,CX_SKIPDIALENTRY,CX_ABORTAREXX };
  15.  
  16.     /* Asynchronous hotkey process. */
  17.  
  18. STATIC struct Process *CxProcess;
  19.  
  20. STATIC struct NewBroker TermBroker =
  21. {
  22.     NB_VERSION,
  23.     "term",
  24.     "term © 1990-1996 by Olaf Barthel",
  25.     "Terminal program",
  26.     0,0,0,NULL,0
  27. };
  28.  
  29.     /* Hotkey(STRPTR Code,struct MsgPort *Port,LONG ID):
  30.      *
  31.      *    A custom version of the amiga.lib supplied code.
  32.      */
  33.  
  34. STATIC CxObj *
  35. CustomHotKey(STRPTR Code,struct MsgPort *Port,LONG ID)
  36. {
  37.     CxObj *Filter;
  38.  
  39.     if(Filter = CxFilter(Code))
  40.     {
  41.         CxObj *Sender;
  42.  
  43.         if(Sender = CxSender(Port,ID))
  44.         {
  45.             CxObj *Translator;
  46.  
  47.             AttachCxObj(Filter,Sender);
  48.  
  49.             if(Translator = CxTranslate(NULL))
  50.             {
  51.                 AttachCxObj(Filter,Translator);
  52.  
  53.                 if(!CxObjError(Filter))
  54.                     return(Filter);
  55.             }
  56.         }
  57.  
  58.         DeleteCxObjAll(Filter);
  59.     }
  60.  
  61.     return(NULL);
  62. }
  63.  
  64.     /* CreateBroker(struct MsgPort *CxPort):
  65.      *
  66.      *    Set up a CxObj commodity broker.
  67.      */
  68.  
  69. STATIC CxObj *
  70. CreateBroker(struct MsgPort *CxPort)
  71. {
  72.     CxObj *Broker;
  73.  
  74.         /* Set the commodity priority. */
  75.  
  76.     TermBroker . nb_Pri = Hotkeys . CommodityPriority;
  77.  
  78.         /* Create the broker. */
  79.  
  80.     if(Broker = CxBroker(&TermBroker,NULL))
  81.     {
  82.             /* Add the hotkeys. */
  83.  
  84.         AttachCxObj(Broker,CustomHotKey(Hotkeys . termScreenToFront,    CxPort,CX_TERMSCREENTOFRONT));
  85.         AttachCxObj(Broker,CustomHotKey(Hotkeys . BufferScreenToFront,    CxPort,CX_BUFFERSCREENTOFRONT));
  86.         AttachCxObj(Broker,CustomHotKey(Hotkeys . SkipDialEntry,    CxPort,CX_SKIPDIALENTRY));
  87.         AttachCxObj(Broker,CustomHotKey(Hotkeys . AbortARexx,        CxPort,CX_ABORTAREXX));
  88.  
  89.             /* Did an error show up? */
  90.  
  91.         if(!CxObjError(Broker))
  92.         {
  93.                 /* Broker has been added, now activate it. */
  94.  
  95.             ActivateCxObj(Broker,Hotkeys . HotkeysEnabled);
  96.  
  97.             return(Broker);
  98.         }
  99.  
  100.         DeleteCxObjAll(Broker);
  101.     }
  102.  
  103.     return(NULL);
  104. }
  105.  
  106.     /* TermCxServer():
  107.      *
  108.      *    Asynchronous hotkey server.
  109.      */
  110.  
  111. STATIC VOID __saveds
  112. TermCxServer(VOID)
  113. {
  114.     CxObj        *Broker;
  115.     struct MsgPort    *CxPort;
  116.     CxMsg        *Message;
  117.  
  118.         /* Create a reply port. */
  119.  
  120.     if(CxPort = CreateMsgPort())
  121.     {
  122.             /* Add the port to the public list. */
  123.  
  124.         CxPort -> mp_Node . ln_Name = TermBroker . nb_Name;
  125.  
  126.         AddPort(CxPort);
  127.  
  128.             /* Install the port. */
  129.  
  130.         TermBroker . nb_Port = CxPort;
  131.  
  132.             /* Create the broker. */
  133.  
  134.         if(Broker = CreateBroker(CxPort))
  135.         {
  136.             ULONG    SignalSet;
  137.             BOOL    Terminated = FALSE;
  138.  
  139.                 /* Signal father task that we're done. */
  140.  
  141.             Signal(ThisProcess,SIG_HANDSHAKE);
  142.  
  143.                 /* Loop and loop... */
  144.  
  145.             while(!Terminated)
  146.             {
  147.                     /* Wait for some signal. */
  148.  
  149.                 SignalSet = Wait(SIG_KILL | SIG_RESET | PORTMASK(CxPort));
  150.  
  151.                     /* ^C aborts. */
  152.  
  153.                 if(SignalSet & SIG_KILL)
  154.                     Terminated = TRUE;
  155.  
  156.                     /* ^D removes the broker and
  157.                      * creates a new one.
  158.                      */
  159.  
  160.                 if(SignalSet & SIG_RESET)
  161.                 {
  162.                     DeleteCxObjAll(Broker);
  163.  
  164.                     Broker = CreateBroker(CxPort);
  165.                 }
  166.  
  167.                     /* A commodity message. */
  168.  
  169.                 if(SignalSet & PORTMASK(CxPort))
  170.                 {
  171.                     ULONG MessageType,MessageID;
  172.  
  173.                         /* Remove all messages. */
  174.  
  175.                     while(Message = (CxMsg *)GetMsg(CxPort))
  176.                     {
  177.                             /* Extract type and ID. */
  178.  
  179.                         MessageType    = CxMsgID(Message);
  180.                         MessageID    = CxMsgType(Message);
  181.  
  182.                         ReplyMsg((struct Message *)Message);
  183.  
  184.                             /* Take a look at the type... */
  185.  
  186.                         switch(MessageID)
  187.                         {
  188.                                 /* A hotkey was pressed. */
  189.  
  190.                             case CXM_IEVENT:
  191.  
  192.                                 switch(MessageType)
  193.                                 {
  194.                                     case CX_TERMSCREENTOFRONT:
  195.  
  196.                                         Forbid();
  197.  
  198.                                         if(Window)
  199.                                             BumpWindow(TopWindow);
  200.                                         else
  201.                                             Signal(ThisProcess,SIGBREAKF_CTRL_F);
  202.  
  203.                                         Permit();
  204.  
  205.                                         break;
  206.  
  207.                                     case CX_BUFFERSCREENTOFRONT:
  208.  
  209.                                         LaunchBuffer();
  210.                                         break;
  211.  
  212.                                     case CX_SKIPDIALENTRY:
  213.  
  214.                                         Signal(ThisProcess,SIG_SKIP);
  215.                                         break;
  216.  
  217.                                     case CX_ABORTAREXX:
  218.  
  219.                                         if(InRexx)
  220.                                             Signal(ThisProcess,SIG_BREAK);
  221.  
  222.                                         break;
  223.                                 }
  224.  
  225.                                 break;
  226.  
  227.                                 /* An internal commodity command. */
  228.  
  229.                             case CXM_COMMAND:
  230.  
  231.                                 switch(MessageType)
  232.                                 {
  233.                                     case CXCMD_DISABLE:
  234.  
  235.                                         ActivateCxObj(Broker,Hotkeys . HotkeysEnabled = FALSE);
  236.                                         break;
  237.  
  238.                                     case CXCMD_ENABLE:
  239.  
  240.                                         ActivateCxObj(Broker,Hotkeys . HotkeysEnabled = TRUE);
  241.                                         break;
  242.                                 }
  243.  
  244.                                 break;
  245.                         }
  246.                     }
  247.                 }
  248.             }
  249.  
  250.                 /* Remove the broker. */
  251.  
  252.             DeleteCxObjAll(Broker);
  253.         }
  254.  
  255.             /* Remove the port from the public list. */
  256.  
  257.         RemPort(CxPort);
  258.  
  259.             /* Remove all pendig messages. */
  260.  
  261.         while(Message = (CxMsg *)GetMsg(CxPort))
  262.             ReplyMsg((struct Message *)Message);
  263.  
  264.             /* Delete the reply port. */
  265.  
  266.         DeleteMsgPort(CxPort);
  267.     }
  268.  
  269.     Forbid();
  270.  
  271.         /* Clear the task ID. */
  272.  
  273.     CxProcess = NULL;
  274.  
  275.         /* Signal father process that we're done. */
  276.  
  277.     Signal(ThisProcess,SIG_HANDSHAKE);
  278. }
  279.  
  280.     /* ShutdownCx():
  281.      *
  282.      *    Remove the hotkey task.
  283.      */
  284.  
  285. VOID
  286. ShutdownCx()
  287. {
  288.     if(CxProcess)
  289.     {
  290.         Forbid();
  291.  
  292.         Signal(CxProcess,SIG_KILL);
  293.  
  294.         ClrSignal(SIG_HANDSHAKE);
  295.  
  296.         Wait(SIG_HANDSHAKE);
  297.  
  298.         Permit();
  299.     }
  300. }
  301.  
  302.     /* SetupCx():
  303.      *
  304.      *    Create the hotkey task.
  305.      */
  306.  
  307. BOOL
  308. SetupCx()
  309. {
  310.         /* If the task is already running, tell it to
  311.          * update the hotkey settings.
  312.          */
  313.  
  314.     if(CxProcess)
  315.     {
  316.         Signal(CxProcess,SIG_RESET);
  317.  
  318.         return(TRUE);
  319.     }
  320.     else
  321.     {
  322.         Forbid();
  323.  
  324.         if(CxProcess = (struct Process *)CreateNewProcTags(
  325.             NP_Entry,    TermCxServer,
  326.             NP_Name,    "term Hotkey Process",
  327.             NP_Priority,    0,
  328.             NP_WindowPtr,    -1,
  329.         TAG_END))
  330.         {
  331.             ClrSignal(SIG_HANDSHAKE);
  332.  
  333.             Wait(SIG_HANDSHAKE);
  334.         }
  335.  
  336.         Permit();
  337.  
  338.         if(CxProcess)
  339.             return(TRUE);
  340.     }
  341.  
  342.     return(FALSE);
  343. }
  344.  
  345.     /* LoadHotkeys(STRPTR Name,struct Hotkeys *Keys):
  346.      *
  347.      *    Load the hotkey settings from a file.
  348.      */
  349.  
  350. BOOL
  351. LoadHotkeys(STRPTR Name,struct Hotkeys *Keys)
  352. {
  353.     struct IFFHandle    *Handle;
  354.     BOOL             Success = FALSE;
  355.     struct StoredProperty    *Prop;
  356.     struct TermInfo        *TermInfo;
  357.     LONG             Error;
  358.  
  359.     if(Handle = AllocIFF())
  360.     {
  361.         if(Handle -> iff_Stream = Open(Name,MODE_OLDFILE))
  362.         {
  363.             InitIFFasDOS(Handle);
  364.  
  365.             if(!(Error = OpenIFF(Handle,IFFF_READ)))
  366.             {
  367.                 /* Collect version number ID if
  368.                  * available.
  369.                  */
  370.  
  371.                 if(!(Error = PropChunks(Handle,(LONG *)VersionProps,1)))
  372.                 {
  373.                     /* The following line tells iffparse to stop at the
  374.                      * very beginning of a `Type' chunk contained in a
  375.                      * `TERM' FORM chunk.
  376.                      */
  377.  
  378.                     if(!(Error = StopChunk(Handle,ID_TERM,ID_HOTK)))
  379.                     {
  380.                         /* Parse the file... */
  381.  
  382.                         if(!ParseIFF(Handle,IFFPARSE_SCAN))
  383.                         {
  384.                             /* Did we get a version ID? */
  385.  
  386.                             if(Prop = FindProp(Handle,ID_TERM,ID_VERS))
  387.                             {
  388.                                 TermInfo = (struct TermInfo *)Prop -> sp_Data;
  389.  
  390.                                 if((TermInfo -> Version < CONFIG_FILE_VERSION) || (TermInfo -> Version == CONFIG_FILE_VERSION && TermInfo -> Revision < CONFIG_FILE_REVISION))
  391.                                 {
  392.                                     if(ReadChunkBytes(Handle,Keys,sizeof(struct HotkeysOld)) == sizeof(struct HotkeysOld))
  393.                                     {
  394.                                         strcpy(Keys -> AbortARexx,"lshift rshift escape");
  395.  
  396.                                         Success = TRUE;
  397.                                     }
  398.                                     else
  399.                                         Error = IoErr();
  400.                                 }
  401.                                 else
  402.                                 {
  403.                                     if(ReadChunkBytes(Handle,Keys,sizeof(struct Hotkeys)) == sizeof(struct Hotkeys))
  404.                                         Success = TRUE;
  405.                                     else
  406.                                         Error = IoErr();
  407.                                 }
  408.                             }
  409.                         }
  410.                     }
  411.                 }
  412.  
  413.                 CloseIFF(Handle);
  414.             }
  415.  
  416.             Close(Handle -> iff_Stream);
  417.         }
  418.         else
  419.             Error = IoErr();
  420.  
  421.         FreeIFF(Handle);
  422.     }
  423.     else
  424.         Error = ERR_NO_MEM;
  425.  
  426.     if(Error)
  427.         SetIoErr(Error);
  428.  
  429.     return(Success);
  430. }
  431.